import { Texture } from "./Texture";
import { Engine } from "../Engine";

class TextureData extends Texture {
  constructor(opts) {
    super(opts);
  }
  get dimension() {
    return this._dimension;
  }
  set dimension(v) {
    this._dimension = "2d";
  }
  get viewDimension() {
    return this._viewDimension;
  }
  set viewDimension(v) {
    this._viewDimension = "2d";
  }
  compressImageSize(image, maxWidth, maxHeight) {
    // 创建一个canvas元素
    var canvas = document.createElement("canvas");
    var ctx = canvas.getContext("2d");

    // 设置canvas的宽高
    var width = maxWidth;
    var height = maxHeight;
    canvas.width = width;
    canvas.height = height;
    ctx.drawImage(image, 0, 0, image.width, image.height, 0, 0, width,height);
    // 将canvas转换为压缩后的ImageBitmap
    return createImageBitmap(canvas);
  }
  async toGPUAsync() {
    if (!this.image) {
      return;
    }
    let data = this.image;
    // 将uint8array数据转换为Blob对象
    var blob = new Blob([data], { type: 'image/jpeg' });
    var bitmap = await createImageBitmap(blob);
    // 获取图像的宽高
    var width = bitmap.width;
    var height = bitmap.height;
    let outputTexture;
    if (width > 8192 || height > 8192) {
      let scale = Math.max(width, height) / 8192;
      width = Math.ceil(width / scale);
      height = Math.ceil(height / scale);

      // 压缩图像到新尺寸
      data = await this.compressImageSize(bitmap, width, height);
      outputTexture = Engine.instance.device.createTexture({
        size: [width, height],
        format: this.format,
        dimension: this.dimension,
        usage: this.usage,
      });
      Engine.instance.queue.copyExternalImageToTexture(
        { source: data },
        { texture: outputTexture },
        [width, height]
      );
    } else {
      if (this.bigTextureQuality !== 1) {
        if (width > 2048 || height > 2048) {
          // let scale = Math.max(width, height) / 2048;
          width = Math.ceil(width * this.bigTextureQuality);
          height = Math.ceil(height* this.bigTextureQuality);
          data = await this.compressImageSize(bitmap, width, height);
          outputTexture= await this.writeToGPU(width,height,data)
        }else{
          outputTexture=await this.writeToGPU(width,height,bitmap)
        }
      } else {
        outputTexture=await this.writeToGPU(width,height,bitmap)
      }
    }
    let {
      dimension,
      viewDimension,
      format,
      usage,
      sampler,
      multisampled,
      sampleType,
      uvIndex,
      uvTransform,
    } = this;
    return {
      dimension,
      viewDimension,
      format,
      usage,
      sampler,
      multisampled,
      sampleType,
      uvIndex,
      uvTransform,
      texture: outputTexture,
    };
  }
 async writeToGPU(width,height,bitmap){
    const mipLevelCount = this.mipMap ? (Math.floor(Math.log2(Math.max(width, height))) + 1) : 1;
    let  outputTexture = Engine.instance.device.createTexture({
      size: [width, height],
      format: this.format,
      dimension: this.dimension,
      usage: this.usage,
      mipLevelCount: mipLevelCount
    });
    Engine.instance.queue.copyExternalImageToTexture(
      { source: bitmap },
      { texture: outputTexture },
      [width, height]
    );
    this.image = undefined
    if (this.mipMap) {
      const usage = GPUTextureUsage.TEXTURE_BINDING | GPUTextureUsage.COPY_DST | GPUTextureUsage.RENDER_ATTACHMENT;
      const textureDescriptor = {
        size: { width: width, height: height },
        format: this.format,
        usage,
        mipLevelCount,
      };
      await Engine.instance.mipmapGenerator.generateMipmap(outputTexture, textureDescriptor);
    }
    return outputTexture
  }
}
export { TextureData };
